/**
 * Copyright ©2012-2018 HopeHaiyang Corporation, All Rights Reserved
 * http://www.wuhanhope.com
 */
package hope.platform.data.server;

import hope.platform.data.dao.ObservedDataRepository;
import hope.platform.data.domain.ObservedData;
import hope.platform.data.domain.entiry.DataManagement;
import hope.platform.data.domain.entiry.HopeException;
import hope.platform.data.remote.DataManagementService;
import hope.platform.data.remote.ExceptionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * class info
 *
 * @author hujia
 *         Create at 2018/7/6 15:49
 */
@Service
@Slf4j
public class ObservedDataServiceImg implements ObservedDataService {

    @Autowired
    private ObservedDataRepository observedDataRepository;

    @Autowired
    private DataManagementService dataManagementService;

    @Autowired
    private ExceptionService exceptionService;

    private DataManagement dataManagement;

    @Override
    public ObservedData addObservedData(ObservedData observedData) throws Exception {
        dataManagement = dataManagementService.getDataManagementByDataName(observedData.getDataName());
        judgeMaxMinValue(observedData);
        judgeMaxMinIncrement(observedData);
        judgeLowHighValue(observedData);
        judgeLowHighIncrement(observedData);
        return observedDataRepository.save(observedData);
    }

    private void judgeLowHighIncrement(ObservedData observedData) {
        if (observedData.getDataIncrement() < dataManagement.getWarnLowIncrementValue() || observedData.getDataIncrement()
                > dataManagement.getWarnHighIncrementValue()) {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("入库达到临界值.\n");
            setBaseExceptionInfo(stringBuffer, observedData);
            stringBuffer.append("观测数据增量为: ");
            stringBuffer.append(observedData.getDataIncrement());
            stringBuffer.append("\n");
            stringBuffer.append("设定观测数据增量正常临界值最大值为: ");
            stringBuffer.append(dataManagement.getWarnHighIncrementValue());
            stringBuffer.append("\n");
            stringBuffer.append("设定观测数据增量正常临界值最小值为: ");
            stringBuffer.append(dataManagement.getWarnLowIncrementValue());
            stringBuffer.append("\n");
            addException("大小增量值", stringBuffer, observedData);
        }
    }

    private void judgeLowHighValue(ObservedData observedData) {
        if (observedData.getDataValue() < dataManagement.getWarnLowValue() || observedData.getDataValue()
                > dataManagement.getWarnHighValue()) {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("入库达到临界值.\n");
            setBaseExceptionInfo(stringBuffer, observedData);
            stringBuffer.append("观测数据值为: ");
            stringBuffer.append(observedData.getDataValue());
            stringBuffer.append("\n");
            stringBuffer.append("设定观测数据正常临界值最大值为: ");
            stringBuffer.append(dataManagement.getWarnHighValue());
            stringBuffer.append("\n");
            stringBuffer.append("设定观测数据正常临界值最小值为: ");
            stringBuffer.append(dataManagement.getWarnLowValue());
            stringBuffer.append("\n");
            addException("大小值", stringBuffer, observedData);
        }
    }

    private void judgeMaxMinIncrement(ObservedData observedData) throws Exception {
        if (Math.abs(observedData.getDataIncrement()) < dataManagement.getMinIncrement() ||
                observedData.getDataIncrement() > dataManagement.getMaxIncrement()) {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("入库发生错误.\n");
            setBaseExceptionInfo(stringBuffer, observedData);
            stringBuffer.append("观测数据增量值为: ");
            stringBuffer.append(observedData.getDataIncrement());
            stringBuffer.append("\n");
            stringBuffer.append("设定观测数据增量最大值为: ");
            stringBuffer.append(dataManagement.getMaxIncrement());
            stringBuffer.append("\n");
            stringBuffer.append("设定观测数据增量最小值为: ");
            stringBuffer.append(dataManagement.getMinIncrement());
            stringBuffer.append("\n");
            addException("最大最小增量值", stringBuffer, observedData);
        }
    }

    private void judgeMaxMinValue(ObservedData observedData) throws Exception {
        if (observedData.getDataValue() < dataManagement.getMinValue() ||
                observedData.getDataValue() > dataManagement.getMaxValue()) {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("入库发生错误.\n");
            setBaseExceptionInfo(stringBuffer, observedData);
            stringBuffer.append("观测数据值为 ");
            stringBuffer.append(observedData.getDataValue());
            stringBuffer.append("\n");
            stringBuffer.append("设定观测数据正常最大值为: ");
            stringBuffer.append(dataManagement.getMaxValue());
            stringBuffer.append("\n");
            stringBuffer.append("设定观测数据正常最小值为:");
            stringBuffer.append(dataManagement.getMinValue());
            stringBuffer.append("\n");
            addException("最大最小值", stringBuffer, observedData);
        }
    }

    private void setBaseExceptionInfo(StringBuffer stringBuffer, ObservedData observedData) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        stringBuffer.append("观测站点编号为: ");
        stringBuffer.append(observedData.getSerialNumber());
        stringBuffer.append("\n");
        stringBuffer.append("观测数据名称为: ");
        stringBuffer.append(observedData.getDataName());
        stringBuffer.append("\n");
        stringBuffer.append("观测数据发生时间为: ");
        stringBuffer.append(df.format(observedData.getDataTime()));
        stringBuffer.append("\n");
    }

    private void addException(String exceptionType, StringBuffer stringBuffer, ObservedData observedData) {
        HopeException hopeException = new HopeException();
        hopeException.setDataName(dataManagement.getDataName());
        hopeException.setExceptionType(exceptionType);
        hopeException.setSerialNumber(observedData.getSerialNumber());
        hopeException.setContent(stringBuffer.toString());
        exceptionService.addException(hopeException);
    }

    @Override
    public List<ObservedData> getObservedDataBySerialNumberAndDataNameBetweenDataTime(String serialNumber,
                                                                                      String dataName,
                                                                                      Date beginTime,
                                                                                      Date endTime) {
        return observedDataRepository.findBySerialNumberAndDataNameAndDataTimeBetweenOrderByDataTimeAsc(serialNumber,
                dataName, beginTime, endTime);
    }

    @Override
    public List<ObservedData> getObservedDataBetweenDataTime(Date beginTime, Date endTime) {
        return observedDataRepository.findByDataTimeBetween(beginTime, endTime);
    }

    @Override
    public long countObservedDataBySerialNumberAndDataNameBetweenDataTime(String serialNumber,
                                                                          String dataName,
                                                                          Date beginTime,
                                                                          Date endTime) {
        return observedDataRepository.countBySerialNumberAndDataNameAndDataTimeBetween(serialNumber,
                dataName, beginTime, endTime);
    }

    @Override
    public long countBySerialNumberAndDataTimeBetween(String serialNumber, Date beginTime, Date endTime) {
        return observedDataRepository.countBySerialNumberAndDataTimeBetween( serialNumber, beginTime, endTime);
    }
}
